home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Financial / Stopwatch2.3 / Source / ClientInspector.m < prev    next >
Text File  |  1995-06-12  |  9KB  |  411 lines

  1. /*
  2.  * For legal stuff see the file COPYRIGHT
  3.  */
  4. #import "ClientInfo.h"
  5. #import "ClientInspector.h"
  6. #import "SessionEditor.h"
  7. #import "ExpenseEditor.h"
  8. #import "Controller.h"
  9.  
  10. @interface ClientInspector(PRIVATE)
  11. - enableAdd:(BOOL)addFlag delete:(BOOL)delFlag modify:(BOOL)modFlag;
  12. - (void)enableAdd:(BOOL)flag;
  13. - (void)enableModify:(BOOL)flag;
  14. - (void)enableDelete:(BOOL)flag;
  15. - (void)enableUndelete:(BOOL)flag;
  16. - showView:newView mgr:(ViewMgr *)mgr;
  17. - (void)updateButtons;
  18. @end
  19.  
  20. @implementation ClientInspector
  21.  
  22. /*
  23.  * Allow only one ClientInspector object to be created.
  24.  */
  25. + sharedInstance
  26. {
  27.   static id obj;
  28.  
  29.   if ( ! obj ) {
  30.     obj = [[ClientInspector alloc] init];
  31.     [NXApp loadNibSection:"ClientInspector.nib" owner:obj withNames:NO];
  32.   }
  33.  
  34.   return obj;
  35. }
  36.  
  37. + (void)updateButtons
  38. {
  39.   [[self sharedInstance] updateButtons];
  40. }
  41.  
  42. - awakeFromNib
  43. {
  44.   NXRect frameRect;
  45.  
  46.   if (![popUpList isKindOf:[PopUpList class]])
  47.     popUpList = [popUpButton target];
  48.  
  49.   [currentView getFrame:&frameRect];
  50.  
  51.   [[sessionView removeFromSuperview] setFrame:&frameRect];
  52.   [[expenseView removeFromSuperview] setFrame:&frameRect];
  53.   [[clientView  removeFromSuperview] setFrame:&frameRect];
  54.  
  55.   [[panel contentView] replaceSubview:currentView with:sessionView];
  56.   currentView = sessionView;
  57.  
  58.   [viewsPanel free];
  59.   [panel setFrameAutosaveName:"ClientInspector"];
  60.   [self windowDidResize:panel];    /* make swap views adjust to saved size */
  61.  
  62.   [browser setDoubleAction:@selector(browserDoubleClick:)];
  63.   controller = [NXApp delegate];
  64.  
  65.   [self decacheBrowser];    /* requires 'controller' to be set first... */
  66.   [[browser matrixInColumn:0] selectCellAt:0 :0];
  67.   return self;
  68. }
  69.  
  70. - (void)decacheBrowser
  71. {
  72.   ClientInfo *info = [self selectedClient];    /* remember the selection */
  73.   [[controller clientList] sort];         /* in case the name was modified */
  74.   [browser loadColumnZero];            /* redisplay */
  75.   [self selectClient:info];             /* reinstate the selection */
  76. }
  77.  
  78. /*
  79.  * This may be obsolete...
  80.  */
  81. - display
  82. {
  83.   List *clientList = [controller clientList];
  84.  
  85.   /*
  86.    * If there are no clients, force the display the Client View,
  87.    * since it's the only meaningful one.
  88.    */
  89.   if ( [clientList count] == 0 )
  90.     [self showClient:nil];
  91.  
  92.   [currentMgr mgrShow:self];
  93.   [self updateButtons];
  94.   [panel makeKeyAndOrderFront:nil]; /* was just "orderFront:" */
  95.   return self;
  96. }
  97.  
  98. - (void)selectClientAt:(int)row
  99. {
  100.   Matrix *matrix = [browser matrixInColumn:0];
  101.   [matrix selectCellAt:row :0]; 
  102. }
  103.  
  104. - selectClient:(ClientInfo *)info
  105. {
  106.   id matrix = [browser matrixInColumn:0];
  107.   List *clientList = [controller clientList];
  108.   int i = [clientList indexOf:info];
  109.  
  110.   [matrix selectCellAt:i :0];
  111.   return self;
  112. }
  113.  
  114. - addClient:(ClientInfo *)info
  115. {
  116.   List *clientList = [controller clientList];
  117.   
  118.   [clientList addObjectIfAbsent:info];
  119.   [self decacheBrowser];
  120.   [controller decacheBrowser];
  121.   [self selectClient:info];
  122.   return self;
  123. }
  124.  
  125. /*
  126.  * Generic delete button - invoke the delete method of the
  127.  * currently selected view. If the return value is non-nil,
  128.  * we save the modified data structure to disk.
  129.  */
  130. - delete:sender
  131. {
  132.   if ( [currentMgr mgrDelete:self] ) {
  133.     [controller saveClientInfo];
  134.     [self updateButtons];
  135.   }
  136.  
  137.   return self;
  138. }
  139.  
  140. - undelete:sender
  141. {
  142.   if ( [currentMgr mgrUndelete:self] ) {
  143.     [controller saveClientInfo];
  144.     [self updateButtons];
  145.   }    
  146.  
  147.   return self;
  148. }
  149.  
  150. - add:sender
  151. {
  152.   if ( [currentMgr mgrAdd:self] ) {
  153.     [controller saveClientInfo];
  154.     [self updateButtons];
  155.   }
  156.   return self;
  157. }
  158.  
  159. - modify:sender
  160. {
  161.   if ( [currentMgr mgrModify:self] ) {
  162.     [controller saveClientInfo];
  163.     [self updateButtons];
  164.   }
  165.   return self;
  166. }
  167.  
  168. - (void)performAdd
  169. {
  170.   [addButton performClick:self];
  171. }
  172.  
  173. - (void)performModify
  174. {
  175.   [modifyButton performClick:self];
  176. }
  177.  
  178. /*
  179.  * Called when the client is selected in the inspector's top browser
  180.  */
  181. - browserClick:sender
  182. {
  183.   [currentMgr mgrShow:self];
  184.   [self updateButtons];
  185.   return self;
  186. }
  187.  
  188. - browserDoubleClick:sender
  189. {
  190.   if ( [currentMgr mgrDoubleClick:self] ) {
  191.     [controller saveClientInfo];
  192.     [self updateButtons];
  193.   }
  194.  
  195.   return self;
  196. }
  197.  
  198. /*
  199.  * Called by the Client mgr when the delete button is pressed.
  200.  */
  201. - (ClientInfo *)deleteSelectedClient
  202. {
  203.   List *clientList = [controller clientList];
  204.   ClientInfo *info = [clientList removeObject:[self selectedClient]];
  205.   [self decacheBrowser];
  206.   [controller decacheBrowser];
  207.   return info;
  208. }
  209.  
  210. - (ClientInfo *)selectedClient
  211. {
  212.   id matrix = [browser matrixInColumn:0];
  213.   List *clientList = [controller clientList];
  214.   return [clientList objectAt:[matrix selectedRow]];
  215. }
  216.  
  217. /*
  218.  * Called when a new session has been added via the main control panel.
  219.  * This allows the browser to update if necessary.
  220.  */
  221. - updatedInfo:info
  222. {
  223.   if ( info == [self selectedClient] )
  224.     [currentMgr mgrShow:self];    /* force redisplay */
  225.  
  226.   return self;
  227. }
  228.  
  229. /*
  230.  * Delegated methods of NXBrowser
  231.  */
  232. - (int)browser:sender fillMatrix:matrix inColumn:(int)column
  233. {
  234.   List *clientList = [controller clientList];
  235.   int i, count = [clientList count];
  236.   const char *name;
  237.   id cell;
  238.   
  239.   for ( i = 0; i < count; i++ ) {
  240.     [matrix addRow];
  241.     name = [[clientList objectAt:i] clientName];
  242.     cell = [matrix cellAt:i :0];    /* 1 dimen. matrix: always use col 0! */
  243.     [cell setStringValue:name];
  244.     [cell setLoaded:YES];
  245.     [cell setLeaf:YES];
  246.   }
  247.  
  248.   return count ;
  249. }
  250.  
  251. - (void)closeMonth
  252. {
  253.   [sessionMgr forgetDeletions];
  254.   [expenseMgr forgetDeletions];
  255.   [clientMgr  forgetDeletions];
  256. }
  257.  
  258. /*
  259.  * Force button title to the right state. This is necessary
  260.  * because PopupLists are a kludge.
  261.  */
  262. - (void)chooseCell:cell
  263. {
  264.   [popUpButton setTitle:[cell title]];
  265.   [[popUpList itemList] selectCell:cell];
  266. }
  267.  
  268. - showClient:sender
  269. {
  270.   [self chooseCell:clientMenuCell];
  271.   [self showView:clientView mgr:clientMgr];
  272.   return self;
  273. }
  274.  
  275. - showHours:sender
  276. {
  277.   [self chooseCell:sessionMenuCell];
  278.   [self showView:sessionView mgr:sessionMgr];
  279.   return self;
  280. }
  281.  
  282. - showExpenses:sender
  283. {
  284.   [self chooseCell:expenseMenuCell];
  285.   [self showView:expenseView mgr:expenseMgr];
  286.   return self;
  287. }
  288.  
  289. - setDocEdited:(BOOL)flag
  290. {
  291.   [panel setDocEdited:flag];
  292.   return self;
  293. }
  294.  
  295. /*
  296.  * Delegated methods of Window
  297.  */
  298. - windowDidResize:sender
  299. {
  300.   NXRect frameRect;
  301.  
  302.   [currentView getFrame:&frameRect];
  303.  
  304.   /* Tell the other swap views their new size */
  305.   [sessionView setFrame:&frameRect];
  306.   [expenseView setFrame:&frameRect];
  307.   [clientView  setFrame:&frameRect];
  308.   return self;
  309. }
  310.  
  311. @end
  312.  
  313.  
  314. @implementation ClientInspector(PRIVATE)
  315.  
  316. - enableAdd:(BOOL)addFlag delete:(BOOL)delFlag modify:(BOOL)modFlag
  317. {
  318.   [controller enableAdd:addFlag];
  319.   [controller enableModify:modFlag];
  320.  
  321.   [self enableAdd:addFlag];
  322.   [self enableModify:modFlag];
  323.   [self enableDelete:delFlag];
  324.  
  325.   [self enableUndelete:[currentMgr canUndelete]];
  326.   return self;
  327. }
  328.  
  329. - showView:newView mgr:(ViewMgr *)mgr
  330. {
  331.   [panel disableFlushWindow];
  332.  
  333.   if (newView != currentView) {
  334.  
  335.     /* Bail out if the user want to save their edits */
  336.     if ( [currentMgr isEditing] == NO ||
  337.     NXRunAlertPanel( [NXApp appName],
  338.             "Modified data has not been saved",
  339.             "Let me save it!",
  340.             "I don't give a hoot", NULL ) != NX_ALERTDEFAULT ) {
  341.  
  342.       [[panel contentView] replaceSubview:currentView with:newView];
  343.  
  344.       currentView = newView;
  345.       currentMgr  = mgr;
  346.  
  347.       [mgr mgrShow:self];
  348.       [self setDocEdited:[mgr isEditing]];
  349.       [panel display];
  350.       [self updateButtons];
  351.     }
  352.   }
  353.  
  354.   [[panel reenableFlushWindow] flushWindow];
  355.   [panel makeKeyAndOrderFront:nil]; /* was just orderFront: before */
  356.   return self;
  357. }
  358.  
  359. /*
  360.  * These are packaged as methods so we can easily add accelerator
  361.  * keys that are controlled at the same time...
  362.  */
  363. - (void)enableAdd:(BOOL)flag
  364. {
  365.   [addButton setEnabled:flag];
  366. }
  367.  
  368. - (void)enableModify:(BOOL)flag
  369. {
  370.   [modifyButton setEnabled:flag];
  371. }
  372.  
  373. - (void)enableDelete:(BOOL)flag
  374. {
  375.   [controller enableDelete:flag];
  376.   [deleteButton setEnabled:flag]; 
  377. }
  378.  
  379. /*
  380.  * Control the menu item from here...
  381.  */
  382. - (void)enableUndelete:(BOOL)flag
  383. {
  384.   [controller enableUndelete:flag];
  385. }
  386.  
  387. - (void)updateButtons
  388. {
  389.   BOOL flag = ([[controller clientList] count] == 0 ? NO : YES);
  390.  
  391.   [self enableAdd:[currentMgr canAdd]
  392.      delete:[currentMgr canDelete]
  393.      modify:[currentMgr canModify]];
  394.  
  395.   /* Enable these when there are clients */
  396.   [sessionMenuCell setEnabled:flag];
  397.   [expenseMenuCell setEnabled:flag];
  398. }
  399.  
  400. /*
  401.  * First responder method - pass to view manager
  402.  */
  403. - selectAll:sender
  404. {
  405.   if ( [currentMgr respondsTo:@selector(selectAll:)] )
  406.     return [currentMgr selectAll:sender];
  407.  
  408.   return nil;            /* is this the right thing to do? */
  409. }
  410. @end
  411.